
package mx.uach.compiladores;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Clase principal del analizador sintactico predictivo.
 * <ul>
 * <li>sent → expr + termn ;<li>
 * <li>expr → expr + termn | term<li>
 * <li>term → 0|1|2|3|4|5|6|7|8|9|9<li>
 * @author Cristian Manuel Franco Diaz
 * @version 1.0
 * since 27/02/2014
 */
public class AnalizadorSintactico {
  private static final int FIN_SENT = ';';
  private static final int SUMA = '+';
  private static final int RESTA='-';
  
  private int token;
  private String notacion;
  /*
  *Constructor principal de la clase
  */
  public AnalizadorSintactico(){
  this.token=-1;
  this.notacion="";
  
  
  
  /*
  
  Hace referencia a una produccion gramatical, verifica que se componga
  @throws IOException
  
  
  
  */
  
  }
  
  public void iniciarAnalisis() throws IOException{
  this.sent();
  }
    public static void main(String[] args) {
        AnalizadorSintactico analizador = new AnalizadorSintactico();
      try {
          analizador.iniciarAnalisis();
      } catch (IOException ex) {
          System.out.println("Ocurrio una anomalia:" + ex.getMessage());
      }
    }
  
  
  private void sent() throws IOException{
      this.siguiente(this.token);
      this.expr();
      if(this.token== FIN_SENT){
          System.out.println(this.notacion);
      }else{
      throw new Error(String.format(
              "Error de sintaxis, se esperaba %s", (char)FIN_SENT));
      }
  
  }
  /*
  Verifica que la secuencia 
  */
  
  
  private void expr() throws IOException{
      this.term();
      while(true){
          if(this.token == SUMA){
              this.siguiente(SUMA);
              term();
              this.notacion= String.format("%s%s", this.notacion, (char)SUMA);
          }else if(this.token == RESTA){
              this.siguiente(RESTA);
              term();
               this.notacion= String.format("%s%s", this.notacion, (char)RESTA);
          
          }else{
          return;
          }
      }
      
  }
  /*
  Verifica que todas las terminales sean digitos.
  @throws IOException cuando no existe una entrada valida
  
  */
  
  
  private void term() throws IOException{
      if(Character.isDigit((char)this.token)){
      this.notacion= String.format("%s%s", this.notacion, (char)token);
      this.siguiente(this.token);
      }else{
       throw new Error(String.format(
               "Error de sintaxis, token no valido: %s", (char) this.token));
      }
  
  }
  
  /**
   * Verifica que la secuencia de tokens sea valida y no sea corrupta
   * @param token caracter numerico
   * @throws IOException 
   */
  private void siguiente(int token) throws IOException{
  if(this.token == token){
  this.token=System.in.read();
  }else{
   throw new Error(String.format(
           "Error de sintaxis, token No valido: %s", (char) this.token));
  }
      
  }
  
}
